<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Tcl lists</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Tcl, learn Tcl, data type, tutorial, programming language, list, Linux">
<meta name="description" content="This chapter of the Tcl tutorial we cover Tcl lists.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">

<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>



<h1>Tcl lists</h1>

<p>
In this part of the Tcl tutorial, we will talk about lists.
</p>

<p>
Computer programs work with data. Spreadsheets, text editors, calculators or chat clients.
Working with groups of data is a basic programming operation. In Tcl, the <b>list</b>
is a basic data structure. It is an ordered collection of items. Items in 
lists are separated by white space. 
</p>

<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* LargeSquare */
google_ad_slot = "5070696322";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

<p>
Every item of the list is identified by its index. Lists do not
have a fixed length. List elements can be strings, numbers, variables,
files or other lists. We can nest lists into other lists to any
depth. 
</p>



<h2>Creating lists</h2>

<p>
There are several ways, how we can create lists in Tcl.
</p>

<pre class="code">
#!/usr/bin/tclsh

set l1 { 1 2 3 }
set l2 [list one two three]
set l3 [split "1.2.3.4" .]

puts $l1
puts $l2
puts $l3
</pre>

<p>
We create tree lists and print their contents to the console. 
</p>

<pre class="explanation">
set l1 { 1 2 3 }
</pre>

<p>
The basic way to create a list is to put elements of the list
inside the brackets. List elements are separated by space.
</p>

<pre class="explanation">
set l2 [list one two three]
</pre>

<p>
Another way to create a list is to use the <code>list</code>
command.
</p>

<pre class="explanation">
set l3 [split "1.2.3.4" .]
</pre>

<p>
Some Tcl commands return a list as a result. In the above
code line, the <code>split</code> command returns a list of
numbers generated from a string. 
</p>

<pre>
$ ./createlists.tcl
 1 2 3 
one two three
1 2 3 4
</pre>

<p>
Output of the createlists.tcl script.
</p>

<h2>Basic list operations</h2>

<p>
In this section, we introduce some basic operations on lists.
We will mention tree commands, that operate on Tcl lists. 
</p>

<pre class="code">
#!/usr/bin/tclsh

set nums { 1 2 3 4 5 6 7 }

puts [llength $nums]
puts [lindex $nums 2]
puts [lindex $nums 4]
puts [lrange $nums 1 3]
</pre>

<p>
The script defines a list of numbers. We perform
some operations on the list with specific list commands. 
</p>

<pre class="explanation">
puts [llength $nums]
</pre>

<p>
The <code>llength</code> command returns a length of the list. 
</p>

<pre class="explanation">
puts [lindex $nums 2]
</pre>

<p>
The <code>lindex</code> command returns an item on the third
position of the list. The positions in Tcl lists start from 0.
</p>

<pre class="explanation">
puts [lrange $nums 1 3]
</pre>

<p>
The <code>lrange</code> command returns a subset of the list. 
</p>

<pre>
$ ./basicoperations.tcl
7
3
5
2 3 4
</pre>

<p>
Output.
</p>

<h2>Traversing lists</h2>

<p>
Now that we have defined lists and basic list operations, 
we want to go traverse the list elements. We show several ways how 
to go through the list items.
</p>

<pre class="code">
#!/usr/bin/tclsh

foreach item {1 2 3 4 5 6 7 8 9} {

    puts $item
}
</pre>

<p>
We go through list elements with the <code>foreach</code>
command. 
</p>

<pre class="explanation">
foreach item {1 2 3 4 5 6 7 8 9} {

    puts $item
}
</pre>

<p>
Each loop cycle the item variable has a value from 
the list of numbers. 
</p>

<pre>
$ ./traverse1.tcl
1
2
3
4
5
6
7
8
9
</pre>

<p>
Ouput.
</p>

<hr class="btm">

<p>
In the second example we will go through items of the days
list using the while loop.
</p>

<pre class="code">
#!/usr/bin/tclsh

set days [list Monday Tuesday Wednesday Thursday \
    Friday Saturday Sunday]
set n [llength $days]

set i 0

while {$i &lt; $n} {

    puts [lindex $days $i]
    incr i
}
</pre>

<p>
We traverse the list using a while loop. When working with a while
loop, we also need a counter and a number of items in the list. 
</p>

<pre class="explanation">
set days [list Monday Tuesday Wednesday Thursday \
    Friday Saturday Sunday]
</pre>

<p>
We create a list of days. 
</p>

<pre class="explanation">
set n [llength $days]
</pre>

<p>
The length of the list is determined with the <code>llength</code>
command. 
</p>

<pre class="explanation">
set i 0
</pre>

<p>
The is a counter. 
</p>

<pre class="explanation">
while {$i &lt; $n} {

    puts [lindex $days $i]
    incr i
}
</pre>

<p>
The while loop executes the commands in the body, until
the counter is equal to the number of elements in the list. 
</p>

<pre class="explanation">
puts [lindex $days $i]
</pre>

<p>
The <code>lindex</code> returns a value from the list pointed to
by the counter.
</p>

<pre class="explanation">
incr i
</pre>

<p>
The counter is increased.
</p>

<pre>
$ ./traverse2.tcl
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
</pre>

<p>
Output.
</p>



<h2>List operations</h2>

<p>
Now we will have some other list commands. 
</p>

<pre class="code">
#!/usr/bin/tclsh

set nums {4 5 6}
puts $nums

lappend nums 7 8 9
puts $nums

puts [linsert $nums 0 1 2 3]
puts $nums
</pre>

<p>
We have a list of three numbers. 
</p>

<pre class="explanation">
lappend nums 7 8 9
</pre>

<p>
The <code>lappend</code> appends data to the list. 
</p>

<pre class="explanation">
puts [linsert $nums 0 1 2 3]
</pre>

<p>
The <code>linsert</code> inserts elements at a given 
index. The first number is the index. The remaining values
are numbers to be inserted into the list.  The command creates a new lists
and returns it. It does not modify the original list. 
</p>

<pre>
$ ./operations.tcl 
4 5 6
4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9
</pre>

<p>
This is the output of the operations.tcl script. 
</p>

<hr class="btm">

<p>
In the following example, we will concatenate lists, search
for items and replace items in lists. 
</p>

<pre class="code">
#!/usr/bin/tclsh

set animals1 { lion eagle elephant dog cat }
set animals2 { giraffe tiger horse dolphin }

set animals [concat $animals1 $animals2]

puts $animals

puts [lsearch -exact $animals eagle]
puts [lreplace $animals 3 4 buffalo crocodile]
</pre>

<p>
We define two animal lists. We introduce three new commands. 
</p>

<pre class="explanation">
set animals [concat $animals1 $animals2]
</pre>

<p>
The <code>concat</code> command is used to concatenate (add) two
lists. The above line joins two lists and the new list is set to
the animals variable. 
</p>

<pre class="explanation">
puts [lsearch -exact $animals eagle]
</pre>

<p>
With the <code>lsearch</code> command we look for an eagle in the
list. With the <code>-exact</code> option we look for an exact match. 
The command returns the index of the first matching element. Or 
-1 if there is no match. 
</p>

<pre class="explanation">
puts [lreplace $animals 3 4 buffalo crocodile]
</pre>

<p>
The <code>lreplace</code> command replaces dog and cat with
buffalo and crocodile. 
</p>

<pre>
$ ./operations2.tcl
lion eagle elephant dog cat giraffe tiger horse dolphin
1
lion eagle elephant buffalo crocodile giraffe tiger horse dolphin
</pre>

<p>
Example output. 
</p>

<h2>Sorting items</h2>

<p>
In this section, we will show how we can sort 
items in Tcl lists. 
</p>

<pre class="code">
#!/usr/bin/tclsh

set names { John Mary Lenka Veronika Julia Robert }
set nums { 1 5 4 3 6 7 9 2 11 0 8 2 3 }

puts [lsort $names]
puts [lsort -ascii $names]
puts [lsort -ascii -decreasing $names]
puts [lsort -integer -increasing $nums]
puts [lsort -integer -decreasing $nums]
puts [lsort -integer -unique $nums]
</pre>

<p>
To sort list elements, we can use the <code>sort</code> command.
The command does not modify the original list. It returns a new
sorted list of elements. 
</p>

<pre class="explanation">
set names { John Mary Lenka Veronika Julia Robert }
set nums { 1 5 4 3 6 7 9 2 11 0 8 2 3 }
</pre>

<p>
We have two lists. In the first we have strings, in the second
numbers. 
</p>

<pre class="explanation">
puts [lsort $names]
puts [lsort -ascii $names]
</pre>

<p>
The default sorting is the ascii sorting. The elements are sorted
by their positions in the ascii table. 
</p>

<pre class="explanation">
puts [lsort -integer -increasing $nums]
puts [lsort -integer -decreasing $nums]
</pre>

<p>
We treat the values as integers and sort them in 
increasing and decreasing orders. 
</p>

<pre class="explanation">
puts [lsort -integer -unique $nums]
</pre>

<p>
We sort the elements of the list in 
a numerical context in increasing order.
Duplicates will be removed. 
</p>

<pre>
$ ./sorting.tcl
John Julia Lenka Mary Robert Veronika
John Julia Lenka Mary Robert Veronika
Veronika Robert Mary Lenka Julia John
0 1 2 2 3 3 4 5 6 7 8 9 11
11 9 8 7 6 5 4 3 3 2 2 1 0
0 1 2 3 4 5 6 7 8 9 11
</pre>

<p>
Output. 
</p>

<h2>Nested lists</h2>

<p>
In Tcl there can be nested lists; list in other lists. 
</p>

<pre class="explanation">
#!/usr/bin/tclsh

set nums {1 2 {1 2 3 4} {{1 2} {3 4}} 3 4}

puts [llength $nums]
puts [llength [lindex $nums 2]]

puts [lindex $nums 0]
puts [lindex [lindex $nums 2] 1]
puts [lindex [lindex [lindex $nums 3] 1] 1]
</pre>

<p>
This is a simple example with nested lists in Tcl. 
</p>

<pre class="explanation">
set nums {1 2 {1 2 3 4} {{1 2} {3 4}} 3 4}
</pre>

<p>
A list with two nested lists. The second list has
two additional inner nested lists. 
</p>

<pre class="explanation">
puts [llength $nums]
</pre>

<p>
We determine the size of the list. The nested list is counted
as one element.
</p>

<pre class="explanation">
puts [llength [lindex $nums 2]]
</pre>

<p>
In this line, we determine the size of the first nested list, which
is the third element of the main list.
</p>

<pre class="explanation">
puts [lindex $nums 0]
</pre>

<p>
Here we print the first element of the main list. 
</p>

<pre class="explanation">
puts [lindex [lindex $nums 2] 1]
</pre>

<p>
In the above line, we get the second element of the
first nested list. 
</p>

<pre class="explanation">
puts [lindex [lindex [lindex $nums 3] 1] 1]
</pre>

<p>
Here we get the second element of the second inner list
of the inner list located at the 4th position of the main list.
In other words: the inner most command is executed first. 
The <code>[lindex $nums 3]</code> returns {{1 2} {3 4}}. 
Now the second command operates on this returned list. 
<code>[lindex {{1 2} {3 4}} 1]</code> returns {3 4}. Finally, the
last command <code>[lindex {3 4} 1]</code> returns 4, which is printed to
the terminal. 
</p>

<pre>
$ ./nestedlists.tcl
6
4
1
2
4
</pre>

<p>
Output.
</p>


<p>
In this part of the Tcl tutorial, we covered Tcl lists.
</p>

<br>
<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div>
<br>

<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>

<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified April 13, 2011  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

